#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>

#define SERVER_PORT   8888
#define BACKLOG       10

int main(int argc, char **argv)
{
    int sockfd,connfd;
    int ret;
    struct sockaddr_in server_addr = {0};
    struct sockaddr_in client_addr = {0};
    int Addr_Len = sizeof(client_addr); 
    int Client_Num = -1;
    int Recv_Len;
    unsigned char Recv_Buf[1000];

    signal(SIGCHLD,SIG_IGN); /*子进程终止后会发送一个SIGCHLD信号给父进程，将SIGCHLD信号设置为忽略，
                             表示父进程不关心,子进程终止后会自动被系统回收，不会产生僵尸进程。*/

    /* 1、创建套接字 */
    sockfd = socket(AF_INET,SOCK_STREAM,0);
    if(sockfd == -1){
        perror("socket error");
        return -1;
    }

    /* 2、绑定端口号和套接字*/
    server_addr.sin_family = AF_INET;     /* IPV4 */
    server_addr.sin_port = htons(SERVER_PORT);    /* 服务器端口号 */
    server_addr.sin_addr.s_addr = INADDR_ANY;  /* 设置为任何IP地址均可连接服务器 */

    ret =  bind(sockfd, (const struct sockaddr *)&server_addr,sizeof(server_addr));
    if(-1 == ret){
        perror("bind error");
        return -1;
    }

    /* 3、监听客户端*/
    ret =  listen(sockfd, BACKLOG);
    if(ret == -1){
        perror("listen error");
        return -1;
    }

    while(1)
    {
        /* 4、阻塞接收客户端连接并建立连接*/
        connfd = accept(sockfd, (struct sockaddr *)&client_addr, &Addr_Len);
        if(connfd != -1){
            Client_Num++;
            printf("Get connect from client %d : %s\n",  Client_Num, inet_ntoa(client_addr.sin_addr));
            if(!fork())
            {
                while(1)
                {
                    /* 执行子进程*/
                    Recv_Len = recv(connfd,Recv_Buf,999,0);
                    if(Recv_Len <= 0)
                    {
                        close(sockfd);
                        return -1;
                    }
                    else
                    {
                        Recv_Buf[Recv_Len] = '\0';
                        printf("Get Msg From Client %d: %s\n",Client_Num,Recv_Buf);
                    }
                    if(!strncmp(Recv_Buf,"quit",4))
                    {
                        close(connfd);
                        close(sockfd);
                    }
                }
            }
        }
    }
    close(sockfd);
    return 0;
}